#include "../include/MatrixMultiplier.h"

SparseMatrixRLS::SparseMatrixRLS(int r, int c) : rows(r), cols(c) {
    data.resize(rows);
    rowStart.resize(rows + 1, 0);
}

void SparseMatrixRLS::addElement(int row, int col, int value) {
    if (value != 0 && row >= 0 && row < rows && col >= 0 && col < cols) {
        data[row].push_back(col);
        data[row].push_back(value);
    }
}

void SparseMatrixRLS::buildRowLinks() {
    rowStart[0] = 0;
    for (int i = 0; i < rows; i++) {
        rowStart[i + 1] = rowStart[i] + data[i].size() / 2;
    }
}

SparseMatrixRLS SparseMatrixRLS::multiply(const SparseMatrixRLS& other) const {
    if (cols != other.rows) {
        throw invalid_argument("矩阵维度不匹配，无法相乘");
    }
    
    SparseMatrixRLS result(rows, other.cols);
    
    for (int i = 0; i < rows; i++) {
        vector<int> tempResult(other.cols, 0);
        
        for (size_t j = 0; j < data[i].size(); j += 2) {
            int colA = data[i][j];
            int valA = data[i][j + 1];
            
            int rowB = colA;
            for (size_t k = 0; k < other.data[rowB].size(); k += 2) {
                int colB = other.data[rowB][k];
                int valB = other.data[rowB][k + 1];
                tempResult[colB] += valA * valB;
            }
        }
        
        for (int j = 0; j < other.cols; j++) {
            if (tempResult[j] != 0) {
                result.addElement(i, j, tempResult[j]);
            }
        }
    }
    
    result.buildRowLinks();
    return result;
}

void SparseMatrixRLS::printDense() const {
    cout << "稠密矩阵形式:" << endl;
    for (int i = 0; i < rows; i++) {
        vector<int> row(cols, 0);
        
        for (size_t j = 0; j < data[i].size(); j += 2) {
            int col = data[i][j];
            int value = data[i][j + 1];
            row[col] = value;
        }
        
        for (int j = 0; j < cols; j++) {
            cout << row[j] << "\t";
        }
        cout << endl;
    }
}

void SparseMatrixRLS::printSparse() const {
    cout << "稀疏矩阵形式 (行逻辑链接存储):" << endl;
    cout << "行\t列\t值" << endl;
    cout << "----------------" << endl;
    for (int i = 0; i < rows; i++) {
        for (size_t j = 0; j < data[i].size(); j += 2) {
            cout << i << "\t" << data[i][j] << "\t" << data[i][j + 1] << endl;
        }
    }
    
    cout << "\n行起始位置: ";
    for (int i = 0; i <= rows; i++) {
        cout << rowStart[i] << " ";
    }
    cout << endl;
}

void SparseMatrixRLS::interactiveInput(const string& matrixName) {
    cout << "=== 输入 " << matrixName << " ===" << endl;
    cout << "矩阵维度: " << rows << " x " << cols << endl;
    
    while (true) {
        int row = Utils::getIntInput("行号 (0-" + to_string(rows-1) + ", -1结束): ");
        if (row == -1) break;
        if (row < 0 || row >= rows) {
            cout << "行号超出范围！" << endl;
            continue;
        }
        
        int col = Utils::getIntInput("列号 (0-" + to_string(cols-1) + "): ");
        if (col < 0 || col >= cols) {
            cout << "列号超出范围！" << endl;
            continue;
        }
        
        int value = Utils::getIntInput("值: ");
        
        addElement(row, col, value);
        cout << "元素添加成功！" << endl;
        
        char cont;
        cout << "继续添加？(y/n): ";
        cin >> cont;
        Utils::clearInputBuffer();
        if (cont != 'y' && cont != 'Y') break;
    }
    
    buildRowLinks();
}

void MatrixMultiplier::testMatrixMultiplication() {
    cout << "=== 稀疏矩阵乘法测试 ===" << endl;
    
    cout << "\n测试用例1:" << endl;
    SparseMatrixRLS A(2, 3);
    A.addElement(0, 0, 1);
    A.addElement(0, 2, 2);
    A.addElement(1, 1, 3);
    A.buildRowLinks();
    
    SparseMatrixRLS B(3, 2);
    B.addElement(0, 0, 4);
    B.addElement(1, 1, 5);
    B.addElement(2, 0, 6);
    B.buildRowLinks();
    
    cout << "矩阵 A:" << endl;
    A.printDense();
    cout << "\n矩阵 B:" << endl;
    B.printDense();
    
    try {
        auto C = A.multiply(B);
        cout << "\n乘积矩阵 C = A × B:" << endl;
        C.printDense();
        cout << "\n稀疏存储信息:" << endl;
        C.printSparse();
    } catch (const exception& e) {
        cout << "错误: " << e.what() << endl;
    }
    
    cout << "\n测试用例2:" << endl;
    SparseMatrixRLS D(3, 3);
    D.addElement(0, 0, 1);
    D.addElement(1, 1, 2);
    D.addElement(2, 2, 3);
    D.buildRowLinks();
    
    SparseMatrixRLS E(3, 3);
    E.addElement(0, 0, 4);
    E.addElement(1, 1, 5);
    E.addElement(2, 2, 6);
    E.buildRowLinks();
    
    cout << "矩阵 D:" << endl;
    D.printDense();
    cout << "\n矩阵 E:" << endl;
    E.printDense();
    
    try {
        auto F = D.multiply(E);
        cout << "\n乘积矩阵 F = D × E:" << endl;
        F.printDense();
    } catch (const exception& e) {
        cout << "错误: " << e.what() << endl;
    }
}

void MatrixMultiplier::interactiveTest() {
    cout << "=== 稀疏矩阵乘法交互式测试 ===" << endl;
    
    while (true) {
        cout << "\n请选择操作：" << endl;
        cout << "1. 输入两个矩阵进行乘法" << endl;
        cout << "2. 使用默认示例测试" << endl;
        cout << "3. 返回主菜单" << endl;
        
        int choice = Utils::getIntInput("请输入选择 (1-3): ");
        
        if (choice == 3) break;
        
        if (choice == 1) {
            int rowsA = Utils::getIntInput("请输入矩阵A的行数: ");
            int colsA = Utils::getIntInput("请输入矩阵A的列数: ");
            int rowsB = Utils::getIntInput("请输入矩阵B的行数: ");
            int colsB = Utils::getIntInput("请输入矩阵B的列数: ");
            
            if (colsA != rowsB) {
                cout << "错误：矩阵A的列数必须等于矩阵B的行数才能相乘！" << endl;
                continue;
            }
            
            SparseMatrixRLS A(rowsA, colsA);
            A.interactiveInput("矩阵A");
            
            SparseMatrixRLS B(rowsB, colsB);
            B.interactiveInput("矩阵B");
            
            cout << "\n矩阵 A:" << endl;
            A.printDense();
            cout << "\n矩阵 B:" << endl;
            B.printDense();
            
            try {
                auto C = A.multiply(B);
                cout << "\n乘积矩阵 C = A × B:" << endl;
                C.printDense();
                cout << "\n稀疏存储信息:" << endl;
                C.printSparse();
            } catch (const exception& e) {
                cout << "乘法错误: " << e.what() << endl;
            }
            
        } else if (choice == 2) {
            testMatrixMultiplication();
        } else {
            cout << "无效选择！" << endl;
        }
    }
}